﻿/* 
 * 
 * Copyright 2013 Bendsoft. All rights reserved.
 * http://www.bendsoft.com
 * 
 * This code is distributed under the New BSD License (BSD).
 * 
 * @package     Camelot SharePoint Integration Library
 * @codeplex    http://camelottoolkit.codeplex.com
 * @license     New BSD License (BSD)
 * 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Camelot.SharePointConnector.Data;
using Camelot.SharePointIntegration.IntegrationService.Entities;
using Camelot.SharePointIntegration.Client;

namespace Camelot.SharePointIntegration
{
    public sealed class DocumentLibraryDataUtility: DocumentLibraryData
    {
        private DocumentLibraryDataUtility() {}

        public static DocumentLibraryData CreateDocumentLibraryData(string listName, string viewName, Camelot.SharePointConnector.Data.SharePointConnection connection)
        {
            var listId = Guid.Empty;
            if (System.Text.RegularExpressions.Regex.IsMatch(listName, @"^(([0-9a-f]{8})\-([0-9a-f]{4})\-([0-9a-f]{4})\-([0-9a-f]{4})\-([0-9a-f]{12})|\{([0-9a-f]{8})\-([0-9a-f]{4})\-([0-9a-f]{4})\-([0-9a-f]{4})\-([0-9a-f]{12})\})$", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                listId = new Guid(listName);

            using (var siteLists = new DataTable())
            {
                Utilities.ExecuteDataTable("show tables", connection, siteLists);
                foreach (DataRow row in siteLists.Rows)
                {
                    if (((Guid)row["ID"]).CompareTo(listId) == 0 || ((string)row["Title"]).ToLower() == listName.ToLower())
                    {
                        var data = new DocumentLibraryDataUtility()
                        {
                            Description = new ListDescription()
                            {
                                ID = (Guid)(row["ID"]),
                                Title = (string)(row["Title"]),
                                Description = (string)(row["Description"]),
                                Created = (DateTime)(row["Created"]),
                                Modified = (DateTime)(row["Modified"]),
                                LastDeleted = (DateTime)(row["LastDeleted"]),
                                ItemCount = (Int32)(row["ItemCount"]),
                                BaseType = (ListType)(row["BaseType"])
                            }
                        };

                        if (data.Description.BaseType != ListType.DocumentLibrary)
                            throw new Exception("Expected list of type document library");

                        var documents = new DocumentLibraryNodeCollection();

                        using (var dtDocs = new DataTable())
                        {
                            if (!String.IsNullOrEmpty(viewName))
                            {
                                Utilities.ExecuteDataTable(String.Format("select ID, GUID, ServerUrl, ContentType, `File Type`, FileSizeDisplay, Created, `Created By`, Modified, `Modified By`, CheckoutUser, BaseName from `{0}`.`{1}`", data.Description.ID.ToString(), viewName), connection, dtDocs);
                            }
                            else
                            {
                                Utilities.ExecuteDataTable(String.Format("select ID, GUID, ServerUrl, ContentType, `File Type`, FileSizeDisplay, Created, `Created By`, Modified, `Modified By`, CheckoutUser, BaseName from `{0}`", data.Description.ID.ToString()), connection, dtDocs);
                            }

                            foreach (var doc in dtDocs.AsEnumerable().Where(n1 => (string)n1["ContentType"] == "Folder").OrderBy(n2 => n2["BaseName"]))
                            {
                                documents.Add(DocumentLibraryData.CreateDocumentLibraryNode(doc));
                            }

                            foreach (var doc in dtDocs.AsEnumerable().Where(n1 => (string)n1["ContentType"] != "Folder").OrderBy(n2 => n2["BaseName"]))
                            {
                                documents.Add(DocumentLibraryData.CreateDocumentLibraryNode(doc));
                            }
                        }

                        data.Documents = documents;
                        return data;
                    }
                }
            }
            return null;
        }

        public static ListData CreateDocumentLibraryListData(string listName, string viewName, Camelot.SharePointConnector.Data.SharePointConnection connection)
        {
            return ListDataUtility.CreateListData(listName, viewName, new string[] { "ID", "GUID", "ServerUrl", "ContentType", "File Type", "FileSizeDisplay", "Created", "Created By", "Modified", "Modified By", "CheckoutUser", "BaseName" }, false, connection);
        }

        public static DocumentLibraryData CreateDocumentLibraryData(Task task)
        {
            if (!string.IsNullOrEmpty(task.Command.SqlCommand))
                throw new Exception("Parameter not supported in this method: SqlCommand");

            using (var connection = new SharePointConnection(task.Command.ConnectionString))
            {
                connection.Open();
                return CreateDocumentLibraryData(task.Command.ListName, task.Command.ViewName, connection);
            }
        }
    }
}